package com.zhiwen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhiwen.domain.entity.Answer;
import com.zhiwen.domain.entity.Comment;
import com.zhiwen.domain.entity.Question;
import com.zhiwen.domain.entity.User;
import com.zhiwen.service.*;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * 用户行为分析服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserAnalyticsServiceImpl implements UserAnalyticsService {

    private static final String USER_ACTION_KEY = "user:action:";
    private static final String USER_LOGIN_FAIL_KEY = "user:login_fail:";
    private static final String USER_ACTIVITY_KEY = "user:activity:";
    private static final String USER_ABNORMAL_KEY = "user:abnormal:";

    // 用户行为类型
    private static final String ACTION_LOGIN = "login";
    private static final String ACTION_LOGOUT = "logout";
    private static final String ACTION_ASK = "ask";
    private static final String ACTION_ANSWER = "answer";
    private static final String ACTION_COMMENT = "comment";
    private static final String ACTION_VOTE = "vote";
    private static final String ACTION_FOLLOW = "follow";
    private static final String ACTION_COLLECT = "collect";

    private final UserService userService;
    private final QuestionService questionService;
    private final AnswerService answerService;
    private final CommentService commentService;
    private final RedisTemplate<String, Object> redisTemplate;
    // 👇 使用 @Resource 按名称注入
    @Resource(name = "dashboardTaskExecutor") // 指定要注入的 Bean 的名称
    private final Executor dashboardTaskExecutor; // 类型仍然是 Executor

    @Override
    public List<Map<String, Object>> getActivityRanking(int limit) {
        try {
            // 获取所有用户
            List<User> allUsers = userService.list();

            // 计算每个用户的活跃度
            List<Map<String, Object>> usersActivity = new ArrayList<>();
            for (User user : allUsers) {
                // 跳过禁用用户
                if (user.getStatus() == 0) {
                    continue;
                }
                Map<String, Object> userActivity = calculateUserActivityData(user);
                usersActivity.add(userActivity);
            }

            // 按活跃度得分排序
            usersActivity.sort((a, b) -> Integer.compare(
                    (int) b.get("activityScore"),
                    (int) a.get("activityScore")
            ));

            // 返回前limit条记录
            return usersActivity.stream()
                    .limit(limit)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取用户活跃度排行失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 计算用户活跃度数据 (异步优化版)
     */
    private Map<String, Object> calculateUserActivityData(User user) {
        Map<String, Object> userActivity = new HashMap<>();
        // 1. 同步设置用户信息 (这些操作非常快)
        userActivity.put("userId", user.getId());
        userActivity.put("username", user.getUsername());
        userActivity.put("nickname", user.getNickname());
        userActivity.put("avatar", user.getAvatar());
        userActivity.put("role", user.getRole());

        Long userId = user.getId();

        // 2. 异步获取 Redis 数据
        CompletableFuture<List<Object>> redisDataFuture = CompletableFuture.supplyAsync(() -> {
            List<String> redisKeys = Arrays.asList(
                    USER_ACTION_KEY + userId + ":login",
                    USER_ACTION_KEY + userId + ":vote",
                    USER_ACTION_KEY + userId + ":collect",
                    USER_ACTION_KEY + userId + ":follow"
            );
            return redisTemplate.opsForValue().multiGet(redisKeys);
        },dashboardTaskExecutor);

        // 3. 异步获取问题数量
        CompletableFuture<Integer> questionCountFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Question> questionWrapper = new LambdaQueryWrapper<>();
            questionWrapper.eq(Question::getUserId, userId).eq(Question::getDeleted, 0);
            return Math.toIntExact(questionService.count(questionWrapper));
        },dashboardTaskExecutor);

        // 4. 异步获取回答数量
        CompletableFuture<Integer> answerCountFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Answer> answerWrapper = new LambdaQueryWrapper<>();
            answerWrapper.eq(Answer::getUserId, userId).eq(Answer::getDeleted, 0);
            return Math.toIntExact(answerService.count(answerWrapper));
        },dashboardTaskExecutor);

        // 5. 异步获取评论数量
        CompletableFuture<Integer> commentCountFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
            commentWrapper.eq(Comment::getUserId, userId).eq(Comment::getDeleted, 0);
            return Math.toIntExact(commentService.count(commentWrapper));
        },dashboardTaskExecutor);

        // 6. 异步获取最近30天活跃度数据
        // 假设 getRecentActivityData 是一个可能涉及I/O或耗时计算的方法
        CompletableFuture<Map<String, Integer>> recentActivityDataFuture = CompletableFuture.supplyAsync(() ->
                getRecentActivityData(userId, 30)
        ,dashboardTaskExecutor);

        // 7. 异步获取最近一次活跃时间
        // 假设 getLastActiveTime 是一个可能涉及I/O或耗时计算的方法
        CompletableFuture<String> lastActiveTimeFuture = CompletableFuture.supplyAsync(() ->
                getLastActiveTime(userId)
        ,dashboardTaskExecutor);

        // 8. 等待所有异步数据获取操作完成
        CompletableFuture<Void> allDataFetchFutures = CompletableFuture.allOf(
                redisDataFuture,
                questionCountFuture,
                answerCountFuture,
                commentCountFuture,
                recentActivityDataFuture,
                lastActiveTimeFuture
        );

        try {
            // join() 会等待完成，如果发生异常则抛出 CompletionException
            allDataFetchFutures.join();

            // 9. 从 Future 中获取结果
            // get() 会在 join() 之后立即返回，如果join()成功的话
            // 如果原始任务中抛出受检异常，get() 会抛出 ExecutionException
            List<Object> redisValues = redisDataFuture.get();
            int questionCount = questionCountFuture.get();
            int answerCount = answerCountFuture.get();
            int commentCount = commentCountFuture.get();
            Map<String, Integer> recentActivityData = recentActivityDataFuture.get();
            String lastActiveTime = lastActiveTimeFuture.get();

            // 10. 处理 Redis 返回值 (确保索引安全)
            int loginCount = 0, voteCount = 0, collectCount = 0, followCount = 0;
            if (redisValues != null) {
                if (redisValues.size() > 0 && redisValues.get(0) != null) {
                    loginCount = Integer.parseInt(redisValues.get(0).toString());
                }
                if (redisValues.size() > 1 && redisValues.get(1) != null) {
                    voteCount = Integer.parseInt(redisValues.get(1).toString());
                }
                if (redisValues.size() > 2 && redisValues.get(2) != null) {
                    collectCount = Integer.parseInt(redisValues.get(2).toString());
                }
                if (redisValues.size() > 3 && redisValues.get(3) != null) {
                    followCount = Integer.parseInt(redisValues.get(3).toString());
                }
            }

            // 11. 设置统计数据到 userActivity Map
            userActivity.put("questionCount", questionCount);
            userActivity.put("answerCount", answerCount);
            userActivity.put("commentCount", commentCount);
            userActivity.put("loginCount", loginCount);
            userActivity.put("voteCount", voteCount);
            userActivity.put("collectCount", collectCount);
            userActivity.put("followCount", followCount);
            userActivity.put("recentActivityData", recentActivityData);
            userActivity.put("lastActiveTime", lastActiveTime);

            // 12. 计算活跃度得分 (依赖于前面获取的数据)
            int activityScore = calculateActivityScore(
                    questionCount,
                    answerCount,
                    commentCount,
                    loginCount,
                    voteCount,
                    collectCount,
                    followCount
            );
            userActivity.put("activityScore", activityScore);

            // 13. 计算活跃度等级 (依赖于得分)
            String activityLevel = getActivityLevel(activityScore);
            userActivity.put("activityLevel", activityLevel);

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢复中断状态
            // 根据您的错误处理策略进行处理，例如记录日志、返回错误信息或抛出自定义异常
            throw new RuntimeException("User activity data calculation was interrupted.", e);
        } catch (ExecutionException e) {
            // ExecutionException 包装了异步任务中发生的原始异常
            Throwable cause = e.getCause();
            // 可以根据 cause 的类型进行特定处理，例如：
            if (cause instanceof ArithmeticException) {
                // 由 Math.toIntExact 抛出，如果数值过大
                System.err.println("ArithmeticException during async task: " + cause.getMessage());
                // 可以选择记录日志、设置默认值或抛出更具体的异常
            }
            throw new RuntimeException("Error occurred during asynchronous fetching of user activity data.", cause);
        } catch (Exception e) { // 捕获其他 join() 可能抛出的 CompletionException 或 parseInt 异常等
            throw new RuntimeException("An unexpected error occurred while calculating user activity data.", e);
        }

        return userActivity;
    }

    /**
     * 计算用户活跃度数据
     */
   /* private Map<String, Object> calculateUserActivityData(User user) {
        Map<String, Object> userActivity = new HashMap<>();
        userActivity.put("userId", user.getId());
        userActivity.put("username", user.getUsername());
        userActivity.put("nickname", user.getNickname());
        userActivity.put("avatar", user.getAvatar());
        userActivity.put("role", user.getRole());

        // 批量获取Redis数据
        List<String> redisKeys = Arrays.asList(
            USER_ACTION_KEY + user.getId() + ":login",
            USER_ACTION_KEY + user.getId() + ":vote",
            USER_ACTION_KEY + user.getId() + ":collect",
            USER_ACTION_KEY + user.getId() + ":follow"
        );

        // 一次性获取所有Redis数据
        List<Object> redisValues = redisTemplate.opsForValue().multiGet(redisKeys);

        // 处理Redis返回值
        int loginCount = 0, voteCount = 0, collectCount = 0, followCount = 0;
        if (redisValues != null) {
            loginCount = redisValues.get(0) != null ? Integer.parseInt(redisValues.get(0).toString()) : 0;
            voteCount = redisValues.get(1) != null ? Integer.parseInt(redisValues.get(1).toString()) : 0;
            collectCount = redisValues.get(2) != null ? Integer.parseInt(redisValues.get(2).toString()) : 0;
            followCount = redisValues.get(3) != null ? Integer.parseInt(redisValues.get(3).toString()) : 0;
        }

        // 批量获取数据库统计信息
        Long userId = user.getId();
        int questionCount = 0;
        int answerCount = 0;
        int commentCount = 0;

        // 获取问题数量
        LambdaQueryWrapper<Question> questionWrapper = new LambdaQueryWrapper<>();
        questionWrapper.eq(Question::getUserId, userId);
        questionWrapper.eq(Question::getDeleted, 0);
        questionCount = Math.toIntExact(questionService.count(questionWrapper));


        // 获取回答数量
        LambdaQueryWrapper<Answer> answerWrapper = new LambdaQueryWrapper<>();
        answerWrapper.eq(Answer::getUserId, userId);
        answerWrapper.eq(Answer::getDeleted, 0);
        answerCount = Math.toIntExact(answerService.count(answerWrapper));

        // 获取评论数量
        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(Comment::getUserId, userId);
        commentWrapper.eq(Comment::getDeleted, 0);
        commentCount = Math.toIntExact(commentService.count(commentWrapper));

        // 设置统计数据
        userActivity.put("questionCount", questionCount);
        userActivity.put("answerCount", answerCount);
        userActivity.put("commentCount", commentCount);
        userActivity.put("loginCount", loginCount);
        userActivity.put("voteCount", voteCount);
        userActivity.put("collectCount", collectCount);
        userActivity.put("followCount", followCount);

        // 计算最近30天活跃度数据
        Map<String, Integer> recentActivityData = getRecentActivityData(userId, 30);
        userActivity.put("recentActivityData", recentActivityData);

        // 计算活跃度得分
        int activityScore = calculateActivityScore(
                questionCount,
                answerCount,
                commentCount,
                loginCount,
                voteCount,
                collectCount,
                followCount
        );
        userActivity.put("activityScore", activityScore);

        // 计算活跃度等级
        String activityLevel = getActivityLevel(activityScore);
        userActivity.put("activityLevel", activityLevel);

        // 计算最近一次活跃时间
        String lastActiveTime = getLastActiveTime(userId);
        userActivity.put("lastActiveTime", lastActiveTime);

        return userActivity;
    }
*/
    /**
     * 获取最近N天的活跃度数据
     */
    private Map<String, Integer> getRecentActivityData(Long userId, int days) {
        Map<String, Integer> activityData = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        for (int i = 0; i < days; i++) {
            LocalDateTime date = now.minusDays(i);
            String dateStr = date.format(formatter);
            String key = USER_ACTIVITY_KEY + userId + ":" + dateStr;

            // 获取当天的活跃度
            Object value = redisTemplate.opsForValue().get(key);
            int activityValue = 0;
            if (value != null) {
                try {
                    activityValue = Integer.parseInt(value.toString());
                } catch (NumberFormatException e) {
                    log.error("解析活跃度失败: {}", e.getMessage());
                }
            }

            activityData.put(dateStr, activityValue);
        }

        return activityData;
    }

    /**
     * 获取用户最近一次活跃时间
     */
    private String getLastActiveTime(Long userId) {
        LocalDateTime now = LocalDateTime.now();

        for (int i = 0; i < 30; i++) {
            LocalDateTime date = now.minusDays(i);
            String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String key = USER_ACTIVITY_KEY + userId + ":" + dateStr;

            // 检查该日期是否有活跃记录
            Boolean hasKey = redisTemplate.hasKey(key);
            if (Boolean.TRUE.equals(hasKey)) {
                if (i == 0) {
                    return "今天";
                } else if (i == 1) {
                    return "昨天";
                } else {
                    return i + "天前";
                }
            }
        }

        return "一个月前";
    }

    /**
     * 根据活跃度得分获取活跃度等级
     */
    private String getActivityLevel(int activityScore) {
        if (activityScore >= 200) {
            return "非常活跃";
        } else if (activityScore >= 100) {
            return "活跃";
        } else if (activityScore >= 50) {
            return "一般活跃";
        } else if (activityScore >= 20) {
            return "较少活跃";
        } else {
            return "不活跃";
        }
    }

    @Override
    public List<Map<String, Object>> detectAbnormalBehavior(int days) {
        try {
            // 获取所有用户
            List<User> allUsers = userService.list();

            // 存储异常行为记录
            List<Map<String, Object>> abnormalUsers = new ArrayList<>();
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime startTime = now.minusDays(days);

            for (User user : allUsers) {
                // 检测频繁登录失败
                Map<String, Object> loginFailDetection = detectLoginFailure(user.getId());
                if (loginFailDetection != null) {
                    loginFailDetection.put("userId", user.getId());
                    loginFailDetection.put("username", user.getUsername());
                    loginFailDetection.put("nickname", user.getNickname());
                    abnormalUsers.add(loginFailDetection);
                }

                // 检测内容违规
                Map<String, Object> contentViolationDetection = detectContentViolation(user.getId(), startTime);
                if (contentViolationDetection != null) {
                    contentViolationDetection.put("userId", user.getId());
                    contentViolationDetection.put("username", user.getUsername());
                    contentViolationDetection.put("nickname", user.getNickname());
                    abnormalUsers.add(contentViolationDetection);
                }

                // 检测频繁操作
                Map<String, Object> frequentOperationDetection = detectFrequentOperation(user.getId(), startTime);
                if (frequentOperationDetection != null) {
                    frequentOperationDetection.put("userId", user.getId());
                    frequentOperationDetection.put("username", user.getUsername());
                    frequentOperationDetection.put("nickname", user.getNickname());
                    abnormalUsers.add(frequentOperationDetection);
                }

                // 检测异常访问时间
                Map<String, Object> abnormalTimeDetection = detectAbnormalTime(user.getId());
                if (abnormalTimeDetection != null) {
                    abnormalTimeDetection.put("userId", user.getId());
                    abnormalTimeDetection.put("username", user.getUsername());
                    abnormalTimeDetection.put("nickname", user.getNickname());
                    abnormalUsers.add(abnormalTimeDetection);
                }

                // 检测异常IP访问
                Map<String, Object> abnormalIpDetection = detectAbnormalIp(user.getId());
                if (abnormalIpDetection != null) {
                    abnormalIpDetection.put("userId", user.getId());
                    abnormalIpDetection.put("username", user.getUsername());
                    abnormalIpDetection.put("nickname", user.getNickname());
                    abnormalUsers.add(abnormalIpDetection);
                }
            }

            // 按风险级别和时间排序
            abnormalUsers.sort((a, b) -> {
                String riskLevelA = (String) a.get("riskLevel");
                String riskLevelB = (String) b.get("riskLevel");

                if (!riskLevelA.equals(riskLevelB)) {
                    // 高 > 中 > 低
                    if ("高".equals(riskLevelA)) return -1;
                    if ("高".equals(riskLevelB)) return 1;
                    if ("中".equals(riskLevelA)) return -1;
                    return 1;
                } else {
                    // 时间近的优先
                    String timeA = (String) a.get("lastOccurredTime");
                    String timeB = (String) b.get("lastOccurredTime");
                    return timeB.compareTo(timeA);
                }
            });

            return abnormalUsers;
        } catch (Exception e) {
            log.error("检测异常行为失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 检测频繁登录失败
     */
    private Map<String, Object> detectLoginFailure(Long userId) {
        String loginFailKey = USER_LOGIN_FAIL_KEY + userId;
        Long loginFailCount = redisTemplate.opsForValue().increment(loginFailKey, 0);

        if (loginFailCount != null && loginFailCount > 5) {
            Map<String, Object> abnormalBehavior = new HashMap<>();
            abnormalBehavior.put("abnormalType", "频繁登录失败");
            abnormalBehavior.put("abnormalCount", loginFailCount);
            abnormalBehavior.put("lastOccurredTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            abnormalBehavior.put("riskLevel", loginFailCount > 10 ? "高" : "中");
            abnormalBehavior.put("description", "用户在短时间内多次登录失败，可能存在账号被盗风险");
            abnormalBehavior.put("suggestion", "建议锁定账号并通知用户修改密码");

            return abnormalBehavior;
        }

        return null;
    }

    /**
     * 检测内容违规
     */
    private Map<String, Object> detectContentViolation(Long userId, LocalDateTime startTime) {
        // 统计被拒绝的问题数量
        LambdaQueryWrapper<Question> questionWrapper = new LambdaQueryWrapper<>();
        questionWrapper.eq(Question::getUserId, userId);
        questionWrapper.eq(Question::getStatus, 4); // 拒绝状态
        questionWrapper.ge(Question::getCreateTime, startTime);
        int rejectedQuestions = Math.toIntExact(questionService.count(questionWrapper));

        if (rejectedQuestions > 2) {
            Map<String, Object> abnormalBehavior = new HashMap<>();
            abnormalBehavior.put("abnormalType", "内容违规");
            abnormalBehavior.put("abnormalCount", rejectedQuestions);
            abnormalBehavior.put("lastOccurredTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            abnormalBehavior.put("riskLevel", rejectedQuestions > 5 ? "高" : "中");
            abnormalBehavior.put("description", "用户发布的内容多次被拒绝，可能存在违规行为");
            abnormalBehavior.put("suggestion", rejectedQuestions > 5 ? "建议暂时禁用该用户账号" : "建议警告该用户");

            return abnormalBehavior;
        }

        return null;
    }

    /**
     * 检测频繁操作
     */
    private Map<String, Object> detectFrequentOperation(Long userId, LocalDateTime startTime) {
        // 模拟检测频繁操作的逻辑
        String frequentOpKey = USER_ABNORMAL_KEY + userId + ":frequent_op";
        Integer opCount = (Integer) redisTemplate.opsForValue().get(frequentOpKey);

        // 模拟随机异常
        boolean isAbnormal = opCount != null && opCount > 100 || Math.random() < 0.03;

        if (isAbnormal) {
            Map<String, Object> abnormalBehavior = new HashMap<>();
            abnormalBehavior.put("abnormalType", "频繁操作");
            abnormalBehavior.put("abnormalCount", opCount != null ? opCount : (int) (100 + Math.random() * 50));
            abnormalBehavior.put("lastOccurredTime", LocalDateTime.now().minusHours((long) (Math.random() * 24)).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            abnormalBehavior.put("riskLevel", "低");
            abnormalBehavior.put("description", "用户在短时间内进行大量操作，可能是自动化脚本");
            abnormalBehavior.put("suggestion", "建议进行人机验证");

            return abnormalBehavior;
        }

        return null;
    }

    /**
     * 检测异常访问时间
     */
    private Map<String, Object> detectAbnormalTime(Long userId) {
        // 模拟检测异常访问时间的逻辑
        String abnormalTimeKey = USER_ABNORMAL_KEY + userId + ":abnormal_time";
        Boolean hasAbnormalTime = redisTemplate.hasKey(abnormalTimeKey);

        // 模拟随机异常
        boolean isAbnormal = Boolean.TRUE.equals(hasAbnormalTime) || Math.random() < 0.02;

        if (isAbnormal) {
            Map<String, Object> abnormalBehavior = new HashMap<>();
            abnormalBehavior.put("abnormalType", "异常访问时间");
            abnormalBehavior.put("abnormalCount", (int) (3 + Math.random() * 7));
            abnormalBehavior.put("lastOccurredTime", LocalDateTime.now().minusDays((long) (Math.random() * 3)).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            abnormalBehavior.put("riskLevel", "低");
            abnormalBehavior.put("description", "用户在非正常时间段频繁访问系统");
            abnormalBehavior.put("suggestion", "建议关注该用户行为");

            return abnormalBehavior;
        }

        return null;
    }

    /**
     * 检测异常IP访问
     */
    private Map<String, Object> detectAbnormalIp(Long userId) {
        // 模拟检测异常IP访问的逻辑
        String abnormalIpKey = USER_ABNORMAL_KEY + userId + ":abnormal_ip";
        Boolean hasAbnormalIp = redisTemplate.hasKey(abnormalIpKey);

        // 模拟随机异常
        boolean isAbnormal = Boolean.TRUE.equals(hasAbnormalIp) || Math.random() < 0.01;

        if (isAbnormal) {
            Map<String, Object> abnormalBehavior = new HashMap<>();
            abnormalBehavior.put("abnormalType", "异常IP访问");
            abnormalBehavior.put("abnormalCount", (int) (2 + Math.random() * 5));
            abnormalBehavior.put("lastOccurredTime", LocalDateTime.now().minusHours((long) (Math.random() * 48)).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            abnormalBehavior.put("riskLevel", "中");
            abnormalBehavior.put("description", "用户账号在多个异常地区的IP地址登录");
            abnormalBehavior.put("suggestion", "建议通知用户并要求验证身份");

            return abnormalBehavior;
        }

        return null;
    }

    @Override
    public boolean recordUserAction(Long userId, String actionType, Map<String, Object> actionDetail) {
        try {
            String key = USER_ACTION_KEY + userId + ":" + LocalDateTime.now().toLocalDate();

            // 构建用户行为记录
            Map<String, Object> actionRecord = new HashMap<>();
            actionRecord.put("userId", userId);
            actionRecord.put("actionType", actionType);
            actionRecord.put("actionDetail", actionDetail);
            actionRecord.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

            // 保存到Redis
            redisTemplate.opsForList().rightPush(key, actionRecord);

            // 设置过期时间（90天）
            redisTemplate.expire(key, 90, java.util.concurrent.TimeUnit.DAYS);

            // 更新用户行为计数器
            String actionCountKey = USER_ACTION_KEY + userId + ":" + actionType;
            redisTemplate.opsForValue().increment(actionCountKey, 1);

            // 更新当天活跃度
            String activityKey = USER_ACTIVITY_KEY + userId + ":" + LocalDateTime.now().toLocalDate();
            int activityIncrement = getActivityIncrementByActionType(actionType);
            redisTemplate.opsForValue().increment(activityKey, activityIncrement);

            // 设置活跃度数据过期时间（180天）
            redisTemplate.expire(activityKey, 180, java.util.concurrent.TimeUnit.DAYS);

            return true;
        } catch (Exception e) {
            log.error("记录用户行为失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 根据行为类型获取活跃度增量
     */
    private int getActivityIncrementByActionType(String actionType) {
        switch (actionType) {
            case ACTION_ASK:
                return 5;
            case ACTION_ANSWER:
                return 3;
            case ACTION_COMMENT:
                return 1;
            case ACTION_VOTE:
                return 1;
            case ACTION_FOLLOW:
                return 1;
            case ACTION_COLLECT:
                return 2;
            case ACTION_LOGIN:
                return 1;
            default:
                return 0;
        }
    }

    @Override
    public List<Map<String, Object>> getUserActionHistory(Long userId, int days) {
        try {
            List<Map<String, Object>> actionHistory = new ArrayList<>();

            // 查询最近days天的行为记录
            LocalDateTime now = LocalDateTime.now();
            for (int i = 0; i < days; i++) {
                LocalDateTime date = now.minusDays(i);
                String key = USER_ACTION_KEY + userId + ":" + date.toLocalDate();

                // 获取该天的行为记录
                Long size = redisTemplate.opsForList().size(key);
                if (size != null && size > 0) {
                    List<Object> actions = redisTemplate.opsForList().range(key, 0, size - 1);
                    if (actions != null) {
                        for (Object action : actions) {
                            if (action instanceof Map) {
                                @SuppressWarnings("unchecked")
                                Map<String, Object> actionMap = (Map<String, Object>) action;
                                actionHistory.add(actionMap);
                            }
                        }
                    }
                }
            }

            // 按时间排序（降序）
            actionHistory.sort((a, b) -> {
                String timestampA = (String) a.get("timestamp");
                String timestampB = (String) b.get("timestamp");
                return timestampB.compareTo(timestampA);
            });

            // 处理行为类型，添加可读性描述
            for (Map<String, Object> action : actionHistory) {
                String actionType = (String) action.get("actionType");
                String description = getActionTypeDescription(actionType);
                action.put("actionTypeDesc", description);
            }

            return actionHistory;
        } catch (Exception e) {
            log.error("获取用户行为历史失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 获取行为类型的描述
     */
    private String getActionTypeDescription(String actionType) {
        switch (actionType) {
            case ACTION_LOGIN:
                return "登录系统";
            case ACTION_LOGOUT:
                return "退出系统";
            case ACTION_ASK:
                return "发布问题";
            case ACTION_ANSWER:
                return "回答问题";
            case ACTION_COMMENT:
                return "发表评论";
            case ACTION_VOTE:
                return "点赞内容";
            case ACTION_FOLLOW:
                return "关注用户";
            case ACTION_COLLECT:
                return "收藏内容";
            default:
                return "其他操作";
        }
    }

    @Override
    public int calculateUserActivity(Long userId) {
        try {
            // 获取用户
            User user = userService.getById(userId);
            if (user == null) {
                return 0;
            }

            // 计算问题数
            LambdaQueryWrapper<Question> questionWrapper = new LambdaQueryWrapper<>();
            questionWrapper.eq(Question::getUserId, userId);
            questionWrapper.eq(Question::getDeleted, 0);
            int questionCount = Math.toIntExact(questionService.count(questionWrapper));

            // 计算回答数
            LambdaQueryWrapper<Answer> answerWrapper = new LambdaQueryWrapper<>();
            answerWrapper.eq(Answer::getUserId, userId);
            answerWrapper.eq(Answer::getDeleted, 0);
            int answerCount = Math.toIntExact(answerService.count(answerWrapper));

            // 计算评论数
            LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
            commentWrapper.eq(Comment::getUserId, userId);
            commentWrapper.eq(Comment::getDeleted, 0);
            int commentCount = Math.toIntExact(commentService.count(commentWrapper));

            // 从Redis获取其他计数
            String loginKey = USER_ACTION_KEY + userId + ":login";
            Long loginCount = redisTemplate.opsForValue().increment(loginKey, 0);

            String voteKey = USER_ACTION_KEY + userId + ":vote";
            Long voteCount = redisTemplate.opsForValue().increment(voteKey, 0);

            String collectKey = USER_ACTION_KEY + userId + ":collect";
            Long collectCount = redisTemplate.opsForValue().increment(collectKey, 0);

            String followKey = USER_ACTION_KEY + userId + ":follow";
            Long followCount = redisTemplate.opsForValue().increment(followKey, 0);

            // 计算活跃度得分
            return calculateActivityScore(
                    questionCount,
                    answerCount,
                    commentCount,
                    loginCount != null ? loginCount.intValue() : 0,
                    voteCount != null ? voteCount.intValue() : 0,
                    collectCount != null ? collectCount.intValue() : 0,
                    followCount != null ? followCount.intValue() : 0
            );
        } catch (Exception e) {
            log.error("计算用户活跃度失败: {}", e.getMessage());
            return 0;
        }
    }

    /**
     * 计算活跃度得分
     * 权重：问题 * 5 + 回答 * 3 + 评论 * 1 + 点赞 * 0.5 + 收藏 * 1.5 + 关注 * 1 + 登录次数 * 0.1
     */
    private int calculateActivityScore(int questionCount, int answerCount, int commentCount,
                                      int loginCount, int voteCount, int collectCount, int followCount) {
        return questionCount * 5 +
               answerCount * 3 +
               commentCount +
               (int) (voteCount * 0.5) +
               (int) (collectCount * 1.5) +
               followCount +
               (int) (loginCount * 0.1);
    }
}
